Skip to content

Add tanh() intrinsic and rev() handler - #90

Merged
t-kalinowski merged 12 commits into
mainfrom
tanh-rev-handler
Feb 7, 2026
Merged

Add tanh() intrinsic and rev() handler#90
t-kalinowski merged 12 commits into
mainfrom
tanh-rev-handler

Conversation

@t-kalinowski

@t-kalinowski t-kalinowski commented Feb 7, 2026

Copy link
Copy Markdown
Owner

This PR adds tanh() as a supported unary intrinsic and introduces an r2f handler for rev() (with tests).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45c35d32b0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread R/r2f-rev.R Outdated
Comment on lines +33 to +36
if (identical(x@value@mode, "logical") && logical_as_int(x@value)) {
out_val <- Variable("logical", x@value@dims)
return(Fortran(
glue("({base_name}(size({base_name}):1:-1) /= 0)"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve NA logicals when reversing

When the input is a logical vector passed via the bind(c) interface, NA values are stored as NA_LOGICAL (an integer sentinel). The rev() handler booleanizes the reversed storage with (/= 0), which turns any non‑zero value—including NA_LOGICAL—into .true.. That means rev(c(TRUE, NA, FALSE)) will return c(TRUE, TRUE, FALSE) instead of preserving NA. This regression is specific to the new rev() implementation for logical-as-int inputs; consider guarding NA or mapping with merge(1, 0, ...) plus an explicit NA check.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I fixed this by making rev() on bind(c) logicals reverse the underlying integer storage (0/1/NA) without booleanizing, so NA_LOGICAL is preserved on return (commit 00d5d28). To keep masks/compound expressions correct, I added booleanization at logical use sites for non-symbol expressions like rev(m) (ifelse, logical ops, pack/masks, reduction masks) and added stress tests covering these combinations (commit 93137e3). NEWS updated in 8de5547.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up: added a regression test for nested rev() on external logicals with NA (commit efc779a) and fixed rev() hoisting to preserve bind(c) logical integer storage by propagating logical_as_int into the temporary (commit fa20990). This prevents NA_LOGICAL from being coerced to .true. in rev(rev(m)).

@codecov

codecov Bot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.78%. Comparing base (3ef7c49) to head (1b4426b).
⚠️ Report is 13 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #90      +/-   ##
==========================================
+ Coverage   92.76%   92.78%   +0.01%     
==========================================
  Files          27       27              
  Lines        5734     5749      +15     
==========================================
+ Hits         5319     5334      +15     
  Misses        415      415              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

\nrev() on bind(c) logical vectors returns integer storage to preserve NA.\nThis change threads booleanization through logical contexts (ifelse, pack,\nlogical ops, reduction masks) for non-symbol expressions and adds stress tests.
rev() on bind(c) logicals returns integer-backed expressions to preserve storage.\nMake as.integer() and which.max/min handle those expressions without emitting\nMERGE(..., mask=<integer>). Add regression tests.
@t-kalinowski

Copy link
Copy Markdown
Owner Author

Added regression test for integer-backed rev() logical expressions flowing into as.integer() and which.max/min(), and fixed both sites to handle bind(c) integer-backed logical expressions without emitting invalid MERGE(..., mask=) (commit dd0de4e).

Avoid early return in symbol lowering so attr(,'r') and hoist rendering are applied consistently.
For scalar bind(c) logicals, avoid returning the booleanized (m/=0) form; return underlying integer storage so NA_LOGICAL is preserved and assignments stay integer->integer.
@t-kalinowski
t-kalinowski merged commit cdc1967 into main Feb 7, 2026
6 checks passed
@t-kalinowski
t-kalinowski deleted the tanh-rev-handler branch February 14, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant